package com.haha.keymap.v2;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.haha.keymap.v1.CustomColor;
import com.haha.keymap.v1.CustomPoint;
import com.haha.keymap.v1.SkillConfigData;
import com.haha.keymap.v1.SkillInfo;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyAdapter;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;

/**
 * @author shenlinnan
 * @date 2025/7/19 15:31
 */
public class KeyMapper extends JFrame implements NativeKeyListener {

    /**
     * 声明状态标签以便在其他地方访问
     */
    private static JLabel statusLabel;
    /**
     * 单体技能按键和颜色配置
     */
    private final SkillConfigData skillConfigData;
    private final Robot robot;
    private boolean startStatus;
    /**
     * 步骤如果是1就是步骤1,2就是步骤2，依次类推
     */
    private int step = 0;

    public KeyMapper() throws AWTException {
        skillConfigData = getConfigInfo();
        startStatus = false;
        robot = new Robot();
    }

    public static void main(String[] args) throws AWTException {
        KeyMapper keyMapper = new KeyMapper();
        keyMapper.initUi();
    }

    private SkillConfigData getConfigInfo() {
        // 1. 读取JSON文件
        String filePath = "I:\\my-workspace\\haha-maven\\src\\main\\java\\com\\haha\\keymap\\v1\\config.json";
        File file = new File(filePath);
        if (!file.exists()) {
            return null;
        }

        // 2. 创建 Gson 实例（带格式化输出）
        Gson gson = new GsonBuilder().setPrettyPrinting().create();

        try (FileReader reader = new FileReader(filePath)) {
            // 3. 定义 JSON 结构对应的 Java 类型
            java.lang.reflect.Type configType = new TypeToken<SkillConfigData>() {
            }.getType();

            // 4. 解析 JSON 到 Java 对象
            return gson.fromJson(reader, configType);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 配置按钮的界面
     */
    private void showConfigDialog() {
        // 创建配置对话框
        JDialog configDialog = new JDialog(this, "配置向导", true);
        configDialog.setSize(700, 300); // 固定大小
        configDialog.setResizable(false); // 禁止调整大小
        configDialog.setLocationRelativeTo(this);

        // 主内容面板
        JPanel contentPanel = new JPanel(new BorderLayout());

        // 主容器 - 用于垂直排列内容
        JPanel mainContainer = new JPanel();
        mainContainer.setLayout(new BoxLayout(mainContainer, BoxLayout.Y_AXIS));
        mainContainer.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // 内边距
        contentPanel.add(mainContainer, BorderLayout.CENTER);

        // 创建步骤组件
        JLabel step1Label = new JLabel("第一步：切换到游戏界面，将鼠标移动到技能提示图标上靠近中心随意的点上，按下F11");
        JLabel step2Label = new JLabel("第二步：切换到游戏界面，将鼠标移动到技能提示图标上另一个点上，按下F11");

        // 坐标标签
        JLabel coordinateLabel1 = new JLabel("坐标：尚未记录");
        JLabel coordinateLabel2 = new JLabel("坐标：尚未记录");

        // 步骤1面板（左对齐）
        JPanel step1Panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        step1Panel.add(step1Label);

        // 步骤1坐标面板（左对齐）
        JPanel coord1Panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        coord1Panel.add(coordinateLabel1);

        // 步骤2面板（初始隐藏）
        JPanel step2Panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        step2Panel.add(step2Label);
        step2Panel.setVisible(false);

        // 步骤2坐标面板（初始隐藏）
        JPanel coord2Panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        coord2Panel.add(coordinateLabel2);
        coord2Panel.setVisible(false);

        // 向主容器添加组件
        mainContainer.add(step1Panel);
        mainContainer.add(Box.createVerticalStrut(10)); // 行间距
        mainContainer.add(coord1Panel);
        mainContainer.add(Box.createVerticalStrut(20)); // 更大的间距
        mainContainer.add(step2Panel);
        mainContainer.add(Box.createVerticalStrut(10)); // 行间距
        mainContainer.add(coord2Panel);

        // 保存按钮
        JButton saveButton = new JButton("保存配置");
        saveButton.addActionListener(e -> {
            // 保存配置逻辑
            JOptionPane.showMessageDialog(configDialog, "配置已保存");
            configDialog.dispose();
            step = 0;
        });

        // 按钮面板放在对话框底部
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(saveButton);
        contentPanel.add(buttonPanel, BorderLayout.SOUTH);

        // 将内容面板添加到对话框
        configDialog.add(contentPanel);

        // 在对话框关闭时注销监听器
        configDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

        // 添加配置专用的键盘监听器
        NativeKeyListener configListener = new NativeKeyAdapter() {
            @Override
            public void nativeKeyPressed(NativeKeyEvent e) {
                System.out.println("111");
                if (step == 0) {
                    step += 1;
                }
                if (e.getKeyCode() == NativeKeyEvent.VC_F11) {
                    Point mousePos = MouseInfo.getPointerInfo().getLocation();

                    if (step == 1) {
                        // 更新第一步坐标
                        coordinateLabel1.setText(String.format("坐标: (X:%d, Y:%d)", mousePos.x, mousePos.y));

                        // 显示第二步及其坐标
                        step2Panel.setVisible(true);
                        coord2Panel.setVisible(true);

                        step = 2; // 进入第二步
                    } else if (step == 2) {
                        // 更新第二步坐标
                        coordinateLabel2.setText(String.format("坐标: (X:%d, Y:%d)", mousePos.x, mousePos.y));
                    }

                }
            }
        };

        // 注册配置专用监听器
        try {
            GlobalScreen.addNativeKeyListener(configListener);
            System.out.println("配置键盘监听已添加");
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        System.out.println(333);
        configDialog.setVisible(true);

        // 对话框关闭时移除配置监听器
        configDialog.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                GlobalScreen.removeNativeKeyListener(configListener);
                System.out.println("配置键盘监听已移除");
                step = 0; // 退出配置模式
            }
        });
    }

    /**
     * 生成主窗口的方法
     */
    public void initUi() {
        // 创建主窗口
        JFrame frame = new JFrame("键映射器");
        frame.setSize(400, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 使用边界布局
        frame.setLayout(new BorderLayout());

        // 创建主面板并设置布局
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());

        // 创建顶部面板放按钮
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));

        // 创建按钮
        JButton startButton = new JButton("启动");
        startButton.setPreferredSize(new Dimension(100, 40));
        JButton configButton = new JButton("配置");
        configButton.setPreferredSize(new Dimension(100, 40));

        // 创建状态面板（放在左下角）
        JPanel statusPanel = new JPanel();
        // 左对齐
        statusPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        // 默认状态
        statusLabel = new JLabel("已停止");
        // 设置默认颜色
        statusLabel.setForeground(Color.RED);
        statusPanel.add(statusLabel);

        // 设置状态面板边框添加内边距
        statusPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 0));

        // 将按钮添加到面板
        buttonPanel.add(startButton);
        buttonPanel.add(configButton);

        // 添加到主面板
        mainPanel.add(buttonPanel, BorderLayout.CENTER);
        mainPanel.add(statusPanel, BorderLayout.SOUTH);

        // 将面板添加到窗口
        frame.add(mainPanel);

        // 注册全局键盘监听器 - 添加这行
        try {
            GlobalScreen.registerNativeHook();
            GlobalScreen.addNativeKeyListener(this);
            System.out.println("全局键盘监听已注册");

            // 禁用JNativeHook日志
            java.util.logging.Logger.getLogger(GlobalScreen.class.getPackage().getName())
                    .setLevel(java.util.logging.Level.OFF);
        } catch (NativeHookException ex) {
            ex.printStackTrace();
        }

        // 居中显示窗口
        frame.setLocationRelativeTo(null);
        // 显示窗口
        frame.setVisible(true);

        // 开始按钮的动作监听
        startButton.addActionListener(e -> {
            String text = startButton.getText();
            if ("启动".equals(text)) {
                startButton.setText("关闭");
                // 更新状态标签
                statusLabel.setText("已启动");
                statusLabel.setForeground(new Color(0, 150, 0)); // 绿色
                startStatus = true;
            } else {
                startButton.setText("启动");
                // 更新状态标签
                statusLabel.setText("已停止");
                statusLabel.setForeground(Color.RED);
                startStatus = false;
            }
        });

        // 配置按钮的动作监听
        configButton.addActionListener(e -> {
            showConfigDialog();
        });

        // 主窗口关闭事件
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                try {
                    GlobalScreen.unregisterNativeHook();
                } catch (NativeHookException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    @Override
    public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) {

    }

    @Override
    public void nativeKeyPressed(NativeKeyEvent e) {
        System.out.println("监听按键了...");
        // 处理配置模式的按键
        if (step > 0) {
            // 配置模式有自己的监听器，主监听器忽略按键
            return;
        }
        // 如果按的是Q健，那么就是单体输出
        if (e.getKeyCode() == NativeKeyEvent.VC_Q && startStatus) {
            System.out.println("1212121212");
            if (skillConfigData == null) {
                System.out.println("未读取到配置");
                return;
            }
            java.util.List<CustomPoint> pointList = skillConfigData.getPoint();

            List<SkillInfo> skills = skillConfigData.getSkills();
            System.out.println(skills);

            for (int i = 0; i < skills.size(); i++) {
                boolean match = true;
                SkillInfo skillInfo = skills.get(i);
                List<CustomColor> color = skillInfo.getColor();
                System.out.println("执行了" + (i + 1) + "次");

                for (int j = 0; j < color.size(); j++) {
                    CustomPoint customPoint = pointList.get(j);
                    int x = customPoint.getX();
                    int y = customPoint.getY();
                    Color currentColor = robot.getPixelColor(x, y);

                    CustomColor customColor = color.get(j);
                    System.out.println(customColor);
                    System.out.println(currentColor);
                    if (!customColor.compare(currentColor)) {
                        match = false;
                        System.out.println("不匹配");
                        break;
                    }
                }
                if (!match) {
                    continue;
                }
                String keyBinding = skillInfo.getKeyBinding();
                if ("-".equals(keyBinding)) {
                    robot.keyPress(KeyEvent.VK_MINUS);
                    robot.keyRelease(KeyEvent.VK_MINUS);
                }
                if ("=".equals(keyBinding)) {
                    System.out.println("按了.......");
                    robot.keyPress(KeyEvent.VK_EQUALS);
                    robot.keyRelease(KeyEvent.VK_EQUALS);
                }
                if ("3".equals(keyBinding)) {
                    System.out.println("按了.......");
                    robot.keyPress(KeyEvent.VK_3);
                    robot.keyRelease(KeyEvent.VK_3);
                }
                if ("4".equals(keyBinding)) {
                    System.out.println("按了.......");
                    robot.keyPress(KeyEvent.VK_4);
                    robot.keyRelease(KeyEvent.VK_4);
                }
                break;

            }
        }

    }

    @Override
    public void nativeKeyReleased(NativeKeyEvent nativeKeyEvent) {

    }
}
